home *** CD-ROM | disk | FTP | other *** search
-
-
-
- /***********************************************
- *
- * file d:\cips\segment2.c
- *
- * Functions: This file contains
- * find_cutoff_point
- * edge_region
- * gray_shade_region
- * edge_gray_shade_region
- * pixel_grow
- * pixel_label_and_check_neighbors
- * is_close
- * erode_image_array
- * get_edge_region_options
- *
- * Purpose:
- * These function implement the three
- * segmentation techniques in Image
- * Processing part 10.
- *
- * External Calls:
- * wtiff.c - round_off_image_size
- * create_file_if_needed
- * write_array_into_tiff_image
- * tiff.c - read_tiff_header
- * rtiff.c - read_tiff_image
- * numcvrt.c - get_integer
- * edges.c - quick_edge
- * homogeneity
- * difference_edge
- * contrast_edge
- * gaussian_edge
- * range
- * variance
- * detect_edges
- * hist.c - calculate_histogram
- * zero_histogram
- * thresh.c - threshold_image_array
- *
- * Modifications:
- * 5 December 1992 - created
- *
- *************************************************/
-
- #include "cips.h"
-
-
-
- /*******************************************
- *
- * find_cutoff_point(..
- *
- * This function looks at a histogram
- * and sets a cuttoff point at a given
- * percentage of pixels.
- * For example, if percent=0.6, you
- * start at 0 in the histogram and count
- * up until you've hit 60% of the pixels.
- * Then you stop and return that pixel
- * value.
- *
- ********************************************/
-
- find_cutoff_point(histogram, percent, cutoff)
- unsigned long histogram[];
- float percent;
- short *cutoff;
- {
- float fd, fsum, sum_div;
- int i, looking;
- long lc, lr, num=0, sum=0;
-
- sum = 0;
- i = 0;
- lr = (long)(ROWS);
- lc = (long)(COLS);
- num = lr*lc;
- fd = (float)(num);
-
- while(looking){
- fsum = (float)(sum);
- sum_div = fsum/fd;
- if(sum_div >= percent)
- looking = 0;
- else
- sum = sum + histogram[i++];
- } /* ends while looking */
-
- if(i >= 256) i = 255;
- *cutoff = i;
- printf("\nCutoff is %d sum=%ld", *cutoff, sum);
- } /* ends find_cutoff_point */
-
-
-
-
-
- /*******************************************
- *
- * edge_region(..
- *
- * This function segments an image by
- * growing regions inside of edges.
- * The steps are:
- * . detect edges
- * . threshold edge output to a
- * percent value
- * . remove edges from consideration
- * . grow regions
- *
- *******************************************/
-
-
- edge_region(in_name, out_name, the_image, out_image,
- il, ie, ll, le, edge_type, min_area,
- max_area, diff, percent, set_value,
- erode)
- char in_name[], out_name[];
- float percent;
- int edge_type, il, ie, ll, le;
- short diff, erode,
- max_area, min_area,
- set_value,
- the_image[ROWS][COLS],
- out_image[ROWS][COLS];
- {
-
- int a, b, count, i, j, k,
- length, width;
- short cutoff;
- struct tiff_header_struct image_header;
- unsigned long histogram[GRAY_LEVELS+1];
-
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- /***************************
- *
- * Detect the edges. Do
- * not threshold.
- *
- ****************************/
-
- if(edge_type == 1 ||
- edge_type == 2 ||
- edge_type == 3)
- detect_edges(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- edge_type, 0, 0);
-
- if(edge_type == 4){
- quick_edge(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 4 */
-
- if(edge_type == 5){
- homogeneity(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 5 */
-
- if(edge_type == 6){
- difference_edge(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 6 */
-
- if(edge_type == 7){
- contrast_edge(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 7 */
-
- if(edge_type == 8){
- gaussian_edge(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 3, 0, 0);
- } /* ends if 8 */
-
- if(edge_type == 10){
- range(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 3, 0, 0);
- } /* ends if 10 */
-
- if(edge_type == 11){
- variance(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 11 */
-
- /**write_array_into_tiff_image("f:e1.tif", out_image,
- il, ie, ll, le);**/
-
- /* copy out_image to the_image */
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
- /******************************
- *
- * Threshold the edge detector
- * output at a given percent.
- * This eliminates the weak
- * edges.
- *
- *******************************/
- zero_histogram(histogram);
- calculate_histogram(the_image, histogram);
- find_cutoff_point(histogram, percent, &cutoff);
- threshold_image_array(the_image, out_image,
- 255, cutoff, set_value);
- /**write_array_into_tiff_image("f:e2.tif", out_image,
- il, ie, ll, le);**/
-
- if(erode != 0){
- /* copy out_image to the_image */
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
- erode_image_array(the_image, out_image,
- set_value, erode);
- } /* ends if erode */
-
- /**write_array_into_tiff_image("f:e3.tif", out_image,
- il, ie, ll, le);**/
-
- /*******************************
- *
- * Set all the edge values to
- * FORGET_IT so the region
- * growing will not use those
- * points.
- *
- *******************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- if(out_image[i][j] == set_value)
- out_image[i][j] = FORGET_IT;
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
- pixel_grow(the_image, out_image, diff,
- min_area, max_area);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends edge_region */
-
-
-
- /*******************************************
- *
- * gray_shade_region(...
- *
- * This function segments an image by
- * growing regions based only on gray
- * shade.
- *
- *******************************************/
-
-
- gray_shade_region(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- diff, min_area, max_area)
- char in_name[], out_name[];
- int il, ie, ll, le;
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- diff, min_area, max_area;
- {
- int a, b, big_count, count, i, j, k, l,
- not_finished, length, width;
- short temp[3][3];
- struct tiff_header_struct image_header;
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
- pixel_grow(the_image, out_image, diff,
- min_area, max_area);
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends gray_shade_region */
-
-
-
-
-
- /*******************************************
- *
- * edge_gray_shade_region(..
- *
- * This function segments an image by
- * growing gray shade regions inside of
- * edges. It combines the techniques
- * of the edge_region and gray_shade_region
- * functions.
- *
- * The steps are:
- * . detect edges
- * . threshold edge output to a
- * percent value
- * . lay the edges on top of the original
- * image to eliminate them from
- * consideration
- * . grow regions
- *
- *******************************************/
-
- edge_gray_shade_region(in_name, out_name, the_image,
- out_image, il, ie, ll, le, edge_type,
- min_area, max_area, diff, percent,
- set_value, erode)
- char in_name[], out_name[];
- float percent;
- int edge_type, il, ie, ll, le;
- short diff, erode,
- max_area, min_area,
- set_value,
- the_image[ROWS][COLS],
- out_image[ROWS][COLS];
- {
- int a, b, count, i, j, k,
- length, width;
- short cutoff;
- struct tiff_header_struct image_header;
- unsigned long histogram[GRAY_LEVELS+1];
-
- create_file_if_needed(in_name, out_name, out_image);
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- /***************************
- *
- * Detect the edges. Do
- * not threshold.
- *
- ****************************/
-
- if(edge_type == 1 ||
- edge_type == 2 ||
- edge_type == 3)
- detect_edges(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- edge_type, 0, 0);
-
- if(edge_type == 4){
- quick_edge(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 4 */
- if(edge_type == 5){
- homogeneity(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 5 */
-
- if(edge_type == 6){
- difference_edge(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 6 */
-
- if(edge_type == 7){
- contrast_edge(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 7 */
-
- if(edge_type == 8){
- gaussian_edge(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 3, 0, 0);
- } /* ends if 8 */
-
- if(edge_type == 10){
- range(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 3, 0, 0);
- } /* ends if 10 */
-
- if(edge_type == 11){
- variance(in_name, out_name, the_image,
- out_image, il, ie, ll, le,
- 0, 0);
- } /* ends if 11 */
-
- /**write_array_into_tiff_image("f:e1.tif", out_image,
- il, ie, ll, le);**/
-
- /* copy out_image to the_image */
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
-
- /******************************
- *
- * Threshold the edge detector
- * output at a given percent.
- * This eliminates the weak
- * edges.
- *
- *******************************/
-
- zero_histogram(histogram);
- calculate_histogram(the_image, histogram);
- find_cutoff_point(histogram, percent, &cutoff);
- threshold_image_array(the_image, out_image,
- 255, cutoff, set_value);
-
- /**write_array_into_tiff_image("f:e2.tif", out_image,
- il, ie, ll, le);**/
-
- if(erode != 0){
- /* copy out_image to the_image */
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- the_image[i][j] = out_image[i][j];
- erode_image_array(the_image, out_image,
- set_value, erode);
- } /* ends if erode */
-
- /**write_array_into_tiff_image("f:e3.tif", out_image,
- il, ie, ll, le);**/
-
- /*******************************
- *
- * Read the original gray shade
- * image back into the_image.
- *
- *******************************/
-
- read_tiff_image(in_name, the_image, il, ie, ll, le);
-
- /*******************************
- *
- * Overlay the edge values
- * on top of the original
- * image by setting them to
- * FORGET_IT so the region
- * growing will not use those
- * points.
- *
- *******************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- if(out_image[i][j] == set_value)
- the_image[i][j] = FORGET_IT;
-
- /**write_array_into_tiff_image("f:e4.tif", the_image,
- il, ie, ll, le);**/
-
- pixel_grow(the_image, out_image, diff,
- min_area, max_area);
-
- write_array_into_tiff_image(out_name, out_image,
- il, ie, ll, le);
-
- } /* ends edge_gray_shade_region */
-
-
-
-
- /**********************************************
- *
- * pixel_grow(...
- *
- * The function grows regions. It is similar
- * to the grow function in segment.c, but it
- * has several new capabilities. It can
- * eliminate regions if they are too large or
- * too small.
- *
- * It ignores pixels = FORGET_IT. This allows
- * it to ignore edges or regions already
- * eliminated from consideration.
- *
- * It adds pixels to a growing region only if
- * the pixel is close enough to the average gray
- * level of that region.
- *
- ***********************************************/
-
- pixel_grow(input, output, diff, min_area, max_area)
- short input[ROWS][COLS],
- output[ROWS][COLS],
- max_area,
- min_area,
- diff;
- {
- char name[80];
-
- int count,
- first_call,
- i,
- ii,
- j,
- jj,
- object_found,
- pointer,
- pop_i,
- pop_j,
- stack_empty,
- stack_file_in_use;
-
- short g_label, target, sum, stack[STACK_SIZE][2];
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- output[i][j] = 0;
-
- g_label = 2;
- object_found = 0;
- first_call = 1;
-
- /*************************************
- *
- * Now begin the process of growing
- * regions.
- *
- **************************************/
-
- for(i=0; i<ROWS; i++){
- if( (i%4) == 0) printf("\n");
- printf("-i=%3d label=%3d", i, g_label);
- for(j=0; j<COLS; j++){
-
- target = input[i][j];
- sum = target;
- count = 0;
- stack_file_in_use = 0;
- stack_empty = 1;
- pointer = -1;
- /**********************************
- *
- * Search for the first pixel of
- * a region. It must not equal
- * FORGET_IT, and it must be close
- * enough to the target (ave value).
- *
- ***********************************/
-
- if(input[i][j] != FORGET_IT &&
- is_close(input[i][j], target, diff) &&
- output[i][j] == 0){
- pixel_label_and_check_neighbor(input,
- output, &target, &sum,
- &count, stack, g_label,
- &stack_empty, &pointer,
- i, j, diff,
- &stack_file_in_use,
- &first_call);
- object_found = 1;
- } /* ends if is_close */
-
- /*****************************
- *
- * If the stack is not empty,
- * pop the coordinates of
- * the pixel off the stack
- * and check its 8 neighbors.
- *
- *******************************/
-
- while(stack_empty == 0){
- pop_i = stack[pointer][0]; /* POP */
- pop_j = stack[pointer][1]; /* OPERATION */
- --pointer;
- if(pointer <= 0){
- if(stack_file_in_use){
- pop_data_off_of_stack_file(
- stack,
- &pointer,
- &stack_file_in_use);
- } /* ends if stack_file_in_use */
- else{
- pointer = 0;
- stack_empty = 1;
- } /* ends else stack file is
- not in use */
- } /* ends if point <= 0 */
- pixel_label_and_check_neighbor(input,
- output, &target, &sum,
- &count, stack, g_label,
- &stack_empty, &pointer,
- pop_i, pop_j,
- diff, &stack_file_in_use,
- &first_call);
- } /* ends while stack_empty == 0 */
-
- if(object_found == 1){
- object_found = 0;
-
- /**********************************
- *
- * The object must be in the
- * size constraints given by
- * min_area and max_area
- *
- *********************************/
-
- if(count >= min_area &&
- count <= max_area)
- ++g_label;
- /**********************************
- *
- * Remove the object from the
- * output. Set all pixels in the
- * object you are removing to
- * FORGET_IT.
- *
- **********************************/
-
- else{
- for(ii=0; ii<ROWS; ii++){
- for(jj=0; jj<COLS; jj++){
- if(output[ii][jj] == g_label){
- output[ii][jj] = 0;
- input[ii][jj] = FORGET_IT;
- } /* ends if output == g_label */
- } /* ends loop over jj */
- } /* ends loop over ii */
- } /* ends else remove object */
- } /* ends if object_found == 1 */
-
- } /* ends loop over j */
- } /* ends loop over i */
-
- printf("\nGROW> found %d objects", g_label);
-
- } /* ends pixel_grow */
-
-
-
-
-
- /********************************************
- *
- * pixel_label_and_check_neighbors(...
- *
- * This function labels a pixel with an object
- * label and then checks the pixel's 8
- * neighbors. If any of the neigbors are
- * set, then they are also labeled.
- *
- * It also updates the target or ave pixel
- * value of the pixels in the region being
- * grown.
- *
- ***********************************************/
- pixel_label_and_check_neighbor(input_image,
- output_image, target,
- sum, count, stack,
- g_label, stack_empty,
- pointer, r, e, diff,
- stack_file_in_use,
- first_call)
- int *count,
- e,
- *first_call,
- *pointer,
- r,
- *stack_empty,
- *stack_file_in_use;
-
- short input_image[ROWS][COLS],
- output_image[ROWS][COLS],
- g_label,
- *sum,
- *target,
- stack[STACK_SIZE][2],
- diff;
- {
- int already_labeled = 0,
- i, j;
-
- if (output_image[r][e] != 0)
- already_labeled = 1;
-
- output_image[r][e] = g_label;
- *count = *count + 1;
- if(*count > 1){
- *sum = *sum + input_image[r][e];
- *target = *sum / *count;
- }
-
- /***************************************
- *
- * Look at the 8 neighors of the
- * point r,e.
- *
- * Ensure the points are close enough
- * to the target and do not equal
- * FORGET_IT.
- *
- * Ensure the points you are checking
- * are in the image, i.e. not less
- * than zero and not greater than
- * ROWS-1 or COLS-1.
- *
- ***************************************/
-
- for(i=(r-1); i<=(r+1); i++){
- for(j=(e-1); j<=(e+1); j++){
-
- if((i>=0) &&
- (i<=ROWS-1) &&
- (j>=0) &&
- (j<=COLS-1)){
-
- if( input_image[i][j] != FORGET_IT &&
- is_close(input_image[i][j],
- *target, diff) &&
- output_image[i][j] == 0){
- *pointer = *pointer + 1;
- stack[*pointer][0] = i; /* PUSH */
- stack[*pointer][1] = j; /* OPERATION */
- *stack_empty = 0;
-
- if(*pointer >= (STACK_SIZE -
- STACK_FILE_LENGTH)){
- push_data_onto_stack_file(stack,
- pointer, first_call);
- *stack_file_in_use = 1;
- } /* ends if *pointer >=
- STACK_SIZE - STACK_FILE_LENGTH*/
-
- } /* ends if is_close */
- } /* end if i and j are on the image */
- } /* ends loop over i rows */
- } /* ends loop over j columns */
- } /* ends pixel_label_and_check_neighbors */
-
-
-
- /********************************************
- *
- * is_close(...
- *
- * This function tests to see if two pixel
- * values are close enough together. It
- * uses the delta parameter to make this
- * judgement.
- *
- ***********************************************/
-
- is_close(a, b, delta)
- short a, b, delta;
- {
- int result = 0;
- short diff;
-
- diff = a-b;
- if(diff < 0) diff = diff*(-1);
- if(diff < delta)
- result = 1;
- return(result);
- } /* ends is_close */
-
-
-
-
- /*******************************************
- *
- * erode_image_array(..
- *
- * This function erodes pixels. If a pixel
- * equals value and has more than threshold
- * neighbors equal to 0, then set that
- * pixel in the output to 0.
- *
- *******************************************/
-
-
- erode_image_array(the_image, out_image,
- value, threshold)
- short the_image[ROWS][COLS],
- out_image[ROWS][COLS],
- threshold,
- value;
- {
- int a, b, count, i, j, k,
- length, width;
-
- /***************************
- *
- * Loop over image array
- *
- ****************************/
-
- for(i=0; i<ROWS; i++)
- for(j=0; j<COLS; j++)
- out_image[i][j] = the_image[i][j];
-
- printf("\n");
-
- for(i=1; i<ROWS-1; i++){
- if( (i%10) == 0) printf("%3d", i);
- for(j=1; j<COLS-1; j++){
- if(the_image[i][j] == value){
- count = 0;
- for(a=-1; a<=1; a++){
- for(b=-1; b<=1; b++){
- if(the_image[i+a][j+b] == 0)
- count++;
- } /* ends loop over b */
- } /* ends loop over a */
- if(count > threshold) out_image[i][j] = 0;
- } /* ends if the_image == value */
- } /* ends loop over j */
- } /* ends loop over i */
-
- } /* ends erode_image_array */
-
-
-
-
-
- /********************************************
- *
- * get_edge_region_options(...
- *
- * This function interacts with the user to
- * get the options needed to call the
- * edge and region based segmentation
- * routines.
- *
- ********************************************/
-
- get_edge_region_options(method, edge_type,
- min_area, max_area, set_value,
- diff, percent, erode)
- char method[];
- float *percent;
- int *edge_type;
- short *diff, *erode,
- *min_area, *max_area,
- *set_value;
- {
- int not_finished = 1, response;
-
- while(not_finished){
- printf("\n\nEdge Region Segmentation Options:");
- printf("\n\t1. Method is %s", method);
- printf("\n\t Recall: Edge, Gray shade, "
- "Combination");
- printf("\n\t2. Edge type is %d", *edge_type);
- printf("\n\t Recall: ");
- printf("\n\t 1=Prewitt 2=Kirsch");
- printf("\n\t 3=Sobel 4=quick");
- printf("\n\t 5=homogeneity 6=difference");
- printf("\n\t 7=contrast 8=gaussian");
- printf("\n\t 10=range 11=variance");
- printf("\n\t3. Min area is %d", *min_area);
- printf("\n\t4. Max area is %d", *max_area);
- printf("\n\t5. Set value is %d", *set_value);
- printf("\n\t6. Difference value is %d", *diff);
- printf("\n\t7. Threshold percentage is %f",
- *percent);
- printf("\n\t8. Erode is %d", *erode);
- printf("\n\nEnter choice (0 = no change) _\b");
-
- get_integer(&response);
-
- if(response == 0){
- not_finished = 0;
- }
-
- if(response == 1){
- printf("\n\t Recall: Edge, Gray shade, "
- "Combination");
- printf("\n\t> ");
- gets(method);
- }
-
- if(response == 2){
- printf("\n\t Recall:");
- printf("\n\t 1=Prewitt 2=Kirsch");
- printf("\n\t 3=Sobel 4=quick");
- printf("\n\t 5=homogeneity 6=difference");
- printf("\n\t 7=contrast 8=gaussian");
- printf("\n\t 10=range 11=variance");
- printf("\n\t__\b");
- get_integer(edge_type);
- }
-
- if(response == 3){
- printf("\nEnter min area:__\b\b");
- get_integer(min_area);
- }
-
- if(response == 4){
- printf("\nEnter max area:__\b\b");
- get_integer(max_area);
- }
-
- if(response == 5){
- printf("\nEnter set value:__\b\b");
- get_integer(set_value);
- }
-
- if(response == 6){
- printf("\nEnter difference:__\b\b");
- get_integer(diff);
- }
-
- if(response == 7){
- printf("\nEnter threshold percentage:__\b\b");
- get_float(percent);
- }
-
- if(response == 8){
- printf("\nEnter erode:__\b\b");
- get_integer(erode);
- }
-
- } /* ends while not_finished */
- } /* ends get_edge_region_options */
-